﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using Microsoft.Practices.ESB.Exception.Management;
using Microsoft.Practices.ESB.Resolver;
using Microsoft.Practices.ESB.Resolver.Itinerary.Facts.Repository;
using Microsoft.Practices.ESB.Resolver.Itinerary.DataAccess;
using Microsoft.BizTalk.Message.Interop;
using Microsoft.BizTalk.Component.Interop;
using Microsoft.XLANGs.BaseTypes;
using System.Xml;

namespace BizTalk.ESB.Extensions.Resolvers
{
    public class ItineraryListStaticResolver : IResolveProvider
    {
        private const String ResolverName = "ITINERARY-LIST";
        private IRepositoryProvider _ItineraryRepository;

        public ItineraryListStaticResolver(Microsoft.Practices.ESB.Configuration.Resolver resolverConfig)
        {
            if (resolverConfig == null)
            {
                throw new ArgumentNullException("resolverConfig");
            }
            try
            {
                // PUT THESE THINGS IN THE DICTIONARY THAT GETS RETURNED!  Then can use for using the SqlProvider
                this._ItineraryRepository = new SqlRepositoryProvider(
                    ResolverConfigHelper.ReadResolverConfigByKey(resolverConfig, "connectionStringName"),
                    ResolverConfigHelper.ReadResolverConfigByKey(resolverConfig, "cacheManagerName"),
                    ResolverConfigHelper.ReadResolverConfigByKey(resolverConfig, "cacheTimeout"));
            }
            catch (Exception e)
            {
                EventLogger.Write(MethodBase.GetCurrentMethod(), e);
                throw;
            }
        }

        Dictionary<string, string> IResolveProvider.Resolve(ResolverInfo resolverInfo, XLANGMessage message)
        {
            // Create instance of ItineraryListResolution
            ItineraryListResolution itinerarylistResolution = new ItineraryListResolution();

            // Call ResolveStatic
            return ResolveStatic(resolverInfo.Config, resolverInfo.Resolver, itinerarylistResolution, this._ItineraryRepository);
        }

        Dictionary<string, string> IResolveProvider.Resolve(string config, string resolver, System.Xml.XmlDocument message)
        {
            // Create instance of ItineraryListResolution
            ItineraryListResolution itinerarylistResolution = new ItineraryListResolution();

            // Call ResolveStatic
            return ResolveStatic(config, resolver, itinerarylistResolution, this._ItineraryRepository);
        }

        Dictionary<string, string> IResolveProvider.Resolve(string config, string resolver, IBaseMessage message, IPipelineContext pipelineContext)
        {
            System.Diagnostics.Trace.WriteLine("In STATIC Resolver from Pipeline");

            // Create instance of ItineraryListResolution
            ItineraryListResolution itinerarylistResolution = new ItineraryListResolution();

            // Call ResolveStatic
            return ResolveStatic(config, resolver, itinerarylistResolution, this._ItineraryRepository);
        }

        private static Dictionary<String, String> ResolveStatic(String config, String resolver, ItineraryListResolution resolution, IRepositoryProvider repository)
        {
            // DEBUG
            System.Diagnostics.Trace.WriteLine("CONFIG = " + config);
            System.Diagnostics.Trace.WriteLine("RESOLVER = " + resolver);

            Dictionary<String, String> resolverInfo = new Dictionary<String, String>();
            Dictionary<String, String> resolverDictionary = new Dictionary<String, String>();
            Dictionary<String, String> facts = null;

            // Add keys from config
            // Add keys from resolver string
            // Add keys from resolution
            if (!resolver.Contains(@":\"))
            {
                resolver = resolver + @":\";
            }
            try
            {
                System.Diagnostics.Trace.WriteLine("Getting resolver info for " + resolver);
                facts = ResolverMgr.GetFacts(config, resolver);
                resolution.ItineraryList = ResolverMgr.GetConfigValue(facts, true, "list");
                resolution.ItineraryCount= Convert.ToInt32(resolution.ItineraryList.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).Length);
                ItineraryListResolutionManager.SetResolverDictionary(resolution, resolverDictionary, repository);
                resolverInfo = resolverDictionary;
            }
            catch (Exception e)
            {
                EventLogger.Write(MethodBase.GetCurrentMethod(), e);
                throw;
            }
            finally
            {
                if (facts != null)
                {
                    facts.Clear();
                    facts = null;
                }
                if (resolution != null)
                {
                    resolution = null;
                }
                if (resolverDictionary != null)
                {
                    resolverDictionary = null;
                }
            }

            return resolverInfo;
        }

    }
}
